package com.zndroid.utils.impl;

import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.Build;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Display;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
import android.view.WindowManager;
import android.widget.FrameLayout;

import androidx.annotation.ColorInt;
import androidx.annotation.FloatRange;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresPermission;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.res.ResourcesCompat;
import androidx.core.graphics.ColorUtils;

import com.zndroid.utils.R;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @name:ScreenUtil
 * @author:lazy
 * @email:luzhenyuxfcy@sina.com
 * @date : 2020/7/15 23:47
 * @version:
 * @description:屏幕相关 https://gitee.com/zndroidx/ImmersionBar  这个有相关适配的解决方案，不再重复造轮子了
 */
@SuppressWarnings("unused")
public class ScreenUtil {
    static final int STATUS_BAR_DEFAULT_HEIGHT_DP = 25; // 大部分状态栏都是25dp

    /**
     * 在某些机子上存在不同的density值，所以增加个虚拟值
     */
    static final float sVirtualDensity = -1;
    /**
     * MIUI导航栏显示隐藏标识位
     */
    static final String IMMERSION_MIUI_NAVIGATION_BAR_HIDE_SHOW = "force_fsg_nav_bar";
    /**
     * 导航栏竖屏高度标识位
     */
    static final String IMMERSION_NAVIGATION_BAR_HEIGHT = "navigation_bar_height";
    /**
     * 导航栏横屏高度标识位
     */
    static final String IMMERSION_NAVIGATION_BAR_HEIGHT_LANDSCAPE = "navigation_bar_height_landscape";
    /**
     * EMUI导航栏显示隐藏标识位
     */
    static final String IMMERSION_EMUI_NAVIGATION_BAR_HIDE_SHOW = "navigationbar_is_min";

    int IMMERSION_ID_STATUS_BAR_VIEW = R.id.status_bar_view;

    /**
     * dp -> px
     *
     * @param context context
     * @param dpValue dp
     */
    public int dp2px(Context context, float dpValue) {
        final float density = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * density + 0.5f);
    }

    /**
     * sp -> px
     *
     * @param context context
     * @param spValue sp
     */
    public int sp2px(Context context, float spValue) {
        final float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * scaledDensity + 0.5f);
    }

    /**
     * px -> dp
     *
     * @param context context
     * @param pxValue px
     */
    public int px2dp(Context context, float pxValue) {
        float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5F);
    }

    /**
     * 获取屏幕的宽度
     *
     * @param context context
     * @return width
     */
    public int getScreenWidth(Context context) {
        WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

        assert manager != null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            return manager.getCurrentWindowMetrics().getBounds().width();
        } else {
            Display display = manager.getDefaultDisplay();
            DisplayMetrics metrics = new DisplayMetrics();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                display.getRealMetrics(metrics);
            } else {
                display.getMetrics(metrics);
            }
            return metrics.widthPixels;
        }
    }

    /**
     * 获取屏幕的高度
     *
     * @param context context
     * @return height
     */
    public int getScreenHeight(Context context) {
        WindowManager manager = (WindowManager) context
                .getSystemService(Context.WINDOW_SERVICE);
        assert manager != null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            return manager.getCurrentWindowMetrics().getBounds().height();
        } else {
            Display display = manager.getDefaultDisplay();
            DisplayMetrics metrics = new DisplayMetrics();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                display.getRealMetrics(metrics);
            } else {
                display.getMetrics(metrics);
            }
            return metrics.heightPixels;
        }
    }

    /**
     * 获取屏幕的像素密度
     *
     * @param context context
     * @return density
     */
    public float getDensity(Context context) {
        return context.getResources().getDisplayMetrics().density;
    }

    /**
     * 获得状态栏的高度
     *
     * @param context context
     * @return mStatusHeight
     */
    public int getStatusBarHeight(Context context) {
        DeviceUtil deviceUtil = new DeviceUtil();

        int mStatusbarHeight;

        try {
            int id;
            if (deviceUtil.isMeizu()) {
                id = context.getResources().getIdentifier("status_bar_height_large", "dimen", "android");
            } else {
                id = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
            }
            mStatusbarHeight = context.getResources().getDimensionPixelSize(id);

            if (deviceUtil.isTablet(context)
                    && mStatusbarHeight > dp2px(context, STATUS_BAR_DEFAULT_HEIGHT_DP)) {
                //状态栏高度大于25dp的平板，状态栏通常在下方
                mStatusbarHeight = 0;
            } else {
                if (mStatusbarHeight <= 0) {
                    if (sVirtualDensity == -1) {
                        mStatusbarHeight = dp2px(context, STATUS_BAR_DEFAULT_HEIGHT_DP);
                    } else {
                        mStatusbarHeight = (int) (STATUS_BAR_DEFAULT_HEIGHT_DP * sVirtualDensity + 0.5f);
                    }
                }
            }
        } catch (Throwable t) {
            mStatusbarHeight = dp2px(context, STATUS_BAR_DEFAULT_HEIGHT_DP);
        }

        return mStatusbarHeight;
    }


    /**
     * 获取当前屏幕截图，不包含状态栏
     *
     * @param activity activity
     * @return bp
     */
    public Bitmap snapShotWithoutStatusBar(Activity activity) {
        View view = activity.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        Bitmap bmp = view.getDrawingCache();
        if (bmp == null) {
            return null;
        }
        Rect frame = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
        int statusBarHeight = frame.top;
        Bitmap bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, bmp.getWidth(), bmp.getHeight() - statusBarHeight);
        view.destroyDrawingCache();
        view.setDrawingCacheEnabled(false);

        return bp;
    }

    /**
     * 获取actionbar的像素高度，默认使用android官方兼容包做actionbar兼容
     *
     * @return action bar height
     */
    public int getActionBarHeight(Context context) {
        int actionBarHeight = 0;
        if (context instanceof AppCompatActivity && ((AppCompatActivity) context).getSupportActionBar() != null) {
            actionBarHeight = ((AppCompatActivity) context).getSupportActionBar().getHeight();
        } else if (context instanceof Activity && ((Activity) context).getActionBar() != null) {
            actionBarHeight = ((Activity) context).getActionBar().getHeight();
        }
        if (actionBarHeight != 0) {
            return actionBarHeight;
        }
        final TypedValue tv = new TypedValue();
        if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
            actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
        }
        return actionBarHeight;
    }

    /**
     * set navigation bar color
     */
    public void setNavigationBarColor(@NonNull Activity activity, @ColorInt int color) {
        //判断是否存在导航栏
        if (isHasNavigationBar(activity)) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            }
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        }

        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
            //5.0以上可以直接设置 navigation颜色
            activity.getWindow().setNavigationBarColor(color);
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
            View navigationBar = new View(activity);
            FrameLayout.LayoutParams params;
            params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, getNavigationBarHeight(activity));
            params.gravity = Gravity.BOTTOM;
            navigationBar.setLayoutParams(params);
            navigationBar.setBackgroundColor(color);
            decorView.addView(navigationBar);
        } else {
            //4.4以下无法设置NavigationBar颜色
        }
    }

    /**
     * 设置纯色状态栏
     *
     * @param activity act
     * @param color    color int
     */
    public void setStatusBarColor(@NonNull Activity activity, @ColorInt int color) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            activity.getWindow().setStatusBarColor(color);
        } else {
            setupStatusBarBelowLOLLIPOP(activity, color);
        }
    }

    /**
     * 设置纯色状态栏
     *
     * @param activity your activity
     * @param color    color int
     * @param alpha    alpha
     */
    public void setStatusBarColor(@NonNull Activity activity, @ColorInt int color, @IntRange(from = 0, to = 255) int alpha) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            activity.getWindow().setStatusBarColor(cipherColor(color, alpha));
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            setTranslucentView((ViewGroup) activity.getWindow().getDecorView(), color, alpha);
            setRootView(activity, true);
        }
    }


    /**
     * 设置状态栏渐变颜色
     *
     * @param activity your activity
     * @param view     View of Toolbar
     */
    public void setStatusBarGradientColor(@NonNull Activity activity, View view) {
        ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
        View fakeStatusBarView = decorView.findViewById(android.R.id.custom);
        if (fakeStatusBarView != null) {
            decorView.removeView(fakeStatusBarView);
        }
        setRootView(activity, false);
        setTransparentForWindow(activity);
        setPaddingTop(activity, view);
    }


    /**
     * 增加View的paddingTop,增加的值为状态栏高度 (智能判断，并设置高度)
     *
     * @param context 目标Context
     * @param view    需要增高的View
     */
    public void setPaddingTop(Context context, @NonNull View view) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            ViewGroup.LayoutParams lp = view.getLayoutParams();
            if (lp != null && lp.height > 0 && view.getPaddingTop() == 0) {
                lp.height += getStatusBarHeight(context);
                int a = view.getPaddingTop();
                int b = getStatusBarHeight(context);
                view.setPadding(view.getPaddingLeft(), view.getPaddingTop() + getStatusBarHeight(context),
                        view.getPaddingRight(), view.getPaddingBottom());
            }
        }
    }


    /**
     * 设置透明状态栏
     *
     * @param activity 目标界面
     */
    public void setTransparentForWindow(@NonNull Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
            activity.getWindow()
                    .getDecorView()
                    .setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            activity.getWindow()
                    .setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }

    /**
     * 创建透明View
     *
     * @param viewGroup 目标视图
     * @param color     状态栏颜色值
     * @param alpha     状态栏透明度
     */
    private void setTranslucentView(ViewGroup viewGroup, @ColorInt int color, @IntRange(from = 0, to = 255) int alpha) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            int cipherColor = cipherColor(color, alpha);
            View translucentView = viewGroup.findViewById(android.R.id.custom);
            if (translucentView == null && cipherColor != 0) {
                translucentView = new View(viewGroup.getContext());
                translucentView.setId(android.R.id.custom);
                ViewGroup.LayoutParams params =
                        new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(viewGroup.getContext()));
                viewGroup.addView(translucentView, params);
            }
            if (translucentView != null) {
                translucentView.setBackgroundColor(cipherColor);
            }
        }

    }

    /**
     * 设置根布局参数
     *
     * @param activity         目标activity
     * @param fitSystemWindows 是否预留toolbar的高度
     */
    private void setRootView(Activity activity, boolean fitSystemWindows) {
        ViewGroup parent = activity.findViewById(android.R.id.content);
        for (int i = 0, count = parent.getChildCount(); i < count; i++) {
            View childView = parent.getChildAt(i);
            if (childView instanceof ViewGroup) {
                childView.setFitsSystemWindows(fitSystemWindows);
                ((ViewGroup) childView).setClipToPadding(fitSystemWindows);
            }
        }
    }

    /**
     * 计算alpha色值
     *
     * @param color 状态栏颜色值
     * @param alpha 状态栏透明度
     */
    private int cipherColor(@ColorInt int color, int alpha) {
        if (alpha == 0) {
            return color;
        }
        float a = 1 - alpha / 255f;
        int red = color >> 16 & 0xff;
        int green = color >> 8 & 0xff;
        int blue = color & 0xff;
        red = (int) (red * a + 0.5);
        green = (int) (green * a + 0.5);
        blue = (int) (blue * a + 0.5);
        return 0xff << 24 | red << 16 | green << 8 | blue;
    }

    /**
     * 设置状态栏黑色字体图标，
     * 支持 4.4 以上版本 MIUI 和 Flyme，以及 6.0 以上版本的其他 Android
     *
     * @param activity 需要被处理的 Activity
     */
    public boolean setStatusBarLightMode(@NonNull Activity activity) {
        DeviceUtil deviceUtil = new DeviceUtil();

        // 无语系列：ZTK C2016只能时间和电池图标变色。。。。
        if (new DeviceUtil().isZTKC2016()) {
            return false;
        }

        if (!isSupportStatusBarDarkFont()) {
            return false;
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            if (deviceUtil.isMIUI()) {
                return isMIUICustomStatusBarLightModeImpl() && MIUISetStatusBarLightMode(activity.getWindow(), false);
            } else if (deviceUtil.isFlyme()) {
                return FlymeSetStatusBarLightMode(activity.getWindow(), false);
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                return Android6SetStatusBarLightMode(activity.getWindow(), false);
            }
        }
        return false;
    }

    /**
     * 设置状态栏白色字体图标
     * 支持 4.4 以上版本 MIUI 和 Flyme，以及 6.0 以上版本的其他 Android
     */
    public boolean setStatusBarDarkMode(@NonNull Activity activity) {
        DeviceUtil deviceUtil = new DeviceUtil();
        // 无语系列：ZTK C2016只能时间和电池图标变色。。。。
        if (new DeviceUtil().isZTKC2016()) {
            return false;
        }

        if (!isSupportStatusBarDarkFont()) {
            return false;
        }

        if (deviceUtil.isMIUI()) {
            return MIUISetStatusBarLightMode(activity.getWindow(), true);
        } else if (deviceUtil.isFlyme()) {
            return FlymeSetStatusBarLightMode(activity.getWindow(), true);
        } else {
            return Android6SetStatusBarLightMode(activity.getWindow(), true);
        }
    }

    @TargetApi(Build.VERSION_CODES.M)
    private int changeStatusBarModeRetainFlag(Window window, int out) {
        out = retainSystemUiFlag(window, out, View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
        out = retainSystemUiFlag(window, out, View.SYSTEM_UI_FLAG_FULLSCREEN);
        out = retainSystemUiFlag(window, out, View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
        out = retainSystemUiFlag(window, out, View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
        out = retainSystemUiFlag(window, out, View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
        out = retainSystemUiFlag(window, out, View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
        return out;
    }

    public int retainSystemUiFlag(Window window, int out, int type) {
        int now = window.getDecorView().getSystemUiVisibility();
        if ((now & type) == type) {
            out |= type;
        }
        return out;
    }

    /**
     * 设置状态栏字体图标为深色，Android 6
     *
     * @param window 需要设置的窗口
     * @param light  是否把状态栏字体及图标颜色设置为深色
     * @return boolean 成功执行返回true
     */
    @TargetApi(Build.VERSION_CODES.M)
    private boolean Android6SetStatusBarLightMode(Window window, boolean light) {
        View decorView = window.getDecorView();
        int systemUi = light ? View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR : View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
        systemUi = changeStatusBarModeRetainFlag(window, systemUi);
        decorView.setSystemUiVisibility(systemUi);
        if (new DeviceUtil().isMIUIV9()) {
            // MIUI 9 低于 6.0 版本依旧只能回退到以前的方案
            // https://github.com/Tencent/QMUI_Android/issues/160
            MIUISetStatusBarLightMode(window, light);
        }
        return true;
    }

    /**
     * 设置状态栏字体图标为深色，需要 MIUIV6 以上
     *
     * @param window 需要设置的窗口
     * @param light  是否把状态栏字体及图标颜色设置为深色
     * @return boolean 成功执行返回 true
     */
    public boolean MIUISetStatusBarLightMode(Window window, boolean light) {
        boolean result = false;
        if (window != null) {
            Class<? extends Window> clazz = window.getClass();
            try {
                int darkModeFlag;
                @SuppressLint("PrivateApi") Class<?> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
                Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
                darkModeFlag = field.getInt(layoutParams);
                Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
                if (light) {
                    extraFlagField.invoke(window, darkModeFlag, darkModeFlag);//状态栏透明且黑色字体
                } else {
                    extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字体
                }
                result = true;
            } catch (Exception ignored) {

            }
        }
        return result;
    }

    /**
     * 更改状态栏图标、文字颜色的方案是否是MIUI自家的， MIUI9 && Android 6 之后用回Android原生实现
     * 见小米开发文档说明：https://dev.mi.com/console/doc/detail?pId=1159
     */
    private boolean isMIUICustomStatusBarLightModeImpl() {
        DeviceUtil deviceUtil = new DeviceUtil();
        if (deviceUtil.isMIUIV9() && Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            return true;
        }
        return deviceUtil.isMIUIV5() || deviceUtil.isMIUIV6() ||
                deviceUtil.isMIUIV7() || deviceUtil.isMIUIV8();
    }

    /**
     * 设置状态栏图标为深色和魅族特定的文字风格
     * 可以用来判断是否为 Flyme 用户
     *
     * @param window 需要设置的窗口
     * @param light  是否把状态栏字体及图标颜色设置为深色
     * @return boolean 成功执行返回true
     */
    public boolean FlymeSetStatusBarLightMode(Window window, boolean light) {
        boolean result = false;
        if (window != null) {
            // flyme 在 6.2.0.0A 支持了 Android 官方的实现方案，旧的方案失效
            Android6SetStatusBarLightMode(window, light);

            try {
                WindowManager.LayoutParams lp = window.getAttributes();
                Field darkFlag = WindowManager.LayoutParams.class
                        .getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
                Field meizuFlags = WindowManager.LayoutParams.class
                        .getDeclaredField("meizuFlags");
                darkFlag.setAccessible(true);
                meizuFlags.setAccessible(true);
                int bit = darkFlag.getInt(null);
                int value = meizuFlags.getInt(lp);
                if (light) {
                    value |= bit;
                } else {
                    value &= ~bit;
                }
                meizuFlags.setInt(lp, value);
                window.setAttributes(lp);
                result = true;
            } catch (Exception ignored) {

            }
        }
        return result;
    }

    /**
     * 获取是否全屏
     *
     * @return 是否全屏
     */
    public boolean isFullScreen(Activity activity) {
        boolean ret = false;
        try {
            WindowManager.LayoutParams attrs = activity.getWindow().getAttributes();
            ret = (attrs.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ret;
    }

    /**
     * 设置一个可以自定义颜色的状态栏
     */
    private void setupStatusBarBelowLOLLIPOP(Activity activity, int statusBarColor) {
        ViewGroup mDecorView = (ViewGroup) activity.getWindow().getDecorView();
        View statusBarView = mDecorView.findViewById(IMMERSION_ID_STATUS_BAR_VIEW);
        if (statusBarView == null) {
            statusBarView = new View(activity);
            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));
            params.gravity = Gravity.TOP;
            statusBarView.setLayoutParams(params);
            statusBarView.setVisibility(View.VISIBLE);
            statusBarView.setId(IMMERSION_ID_STATUS_BAR_VIEW);
            mDecorView.addView(statusBarView);
        }

        statusBarView.setBackgroundColor(statusBarColor);
    }

    /**
     * 判断手机支不支持状态栏字体变色
     * Is support status bar dark font boolean.
     *
     * @return the boolean
     */
    public boolean isSupportStatusBarDarkFont() {
        return isMIUI6Later() || isFlymeOS4Later()
                || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M);
    }

    /**
     * 状态栏透明
     * transparent StatusBar
     *
     * @param activity the activity
     */
    public void transparentStatusBar(@NonNull Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            //全透明状态栏(不带阴影)
            activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {/*半透明状态栏(带阴影)*/
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
        /* else {
            //nothing
        } */
    }

    /**
     * 隐藏状态栏
     * Hide status bar.
     *
     * @param window the window
     */
    private void hideStatusBar(@NonNull Window window) {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
            WindowInsetsController windowInsetsController = window.getInsetsController();
            windowInsetsController.hide(WindowInsets.Type.statusBars());
        } else {
            window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                    WindowManager.LayoutParams.FLAG_FULLSCREEN);
        }
    }

    /**
     * 隐藏状态栏
     * Hide status bar.
     *
     * @param activity the activity
     */
    public void hideStatusBar(@NonNull Activity activity) {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
            WindowInsetsController windowInsetsController = activity.getWindow().getInsetsController();
            windowInsetsController.hide(WindowInsets.Type.statusBars());
        } else {
            activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                    WindowManager.LayoutParams.FLAG_FULLSCREEN);
        }
    }

    /**
     * 显示状态栏
     * Show status bar.
     *
     * @param window the window
     */
    private void showStatusBar(@NonNull Window window) {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
            WindowInsetsController windowInsetsController = window.getInsetsController();
            windowInsetsController.show(WindowInsets.Type.statusBars());
        } else {
            window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        }
    }

    /**
     * 显示状态栏
     * Show status bar.
     *
     * @param activity the activity
     */
    public void showStatusBar(@NonNull Activity activity) {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
            WindowInsetsController windowInsetsController = activity.getWindow().getInsetsController();
            windowInsetsController.show(WindowInsets.Type.statusBars());
        } else {
            activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        }
    }

    /**
     * 判断导航栏图标是否支持变色
     * Is support navigation icon dark boolean.
     *
     * @return the boolean
     */
    public boolean isSupportNavigationIconDark() {
        return isMIUI6Later() || Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
    }

    private boolean isMIUI6Later() {
        String version = new DeviceUtil().getMIUIVersionName();
        int num;
        if ((!version.isEmpty())) {
            try {
                num = Integer.parseInt(version.substring(1));
                return num >= 6;
            } catch (NumberFormatException e) {
                return false;
            }
        } else {
            return false;
        }
    }

    /**
     * 隐藏导航栏
     */
    public void hideNavigationBar(@NonNull Activity activity) {
        if (!isHasNavigationBar(activity)) {
            return;
        }

        setNavigationBarColor(activity, ResourcesCompat.getColor(activity.getResources(), android.R.color.transparent, activity.getTheme()));
        hideNavigationBar(activity.getWindow());
    }

    /**
     * 隐藏导航栏
     */
    private void hideNavigationBar(@NonNull Window window) {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
            WindowInsetsController windowInsetsController = window.getInsetsController();
            windowInsetsController.hide(WindowInsets.Type.navigationBars());
        } else {
            View decorView = window.getDecorView();
            // Hide both the navigation bar and the status bar.
            // SYSTEM_UI_FLAG_FULLSCREEN is only available on Android 4.1 and higher, but as
            // a general rule, you should design your app to hide the status bar whenever you
            // hide the navigation bar.
//            请注意以下几点：
//
//            使用这种方法，轻触屏幕上的任意位置都会使导航栏（和状态栏）重新出现并保持可见状态。用户互动会导致这些标记被清除。
//            标记被清除后，如果您希望再次隐藏这些栏，应用需要重置这些标记。请参阅响应界面可见性更改，探讨如何监听界面可见性变化，以便您的应用相应地做出响应。
//            在不同的位置设置界面标记会产生不同的效果。如果您在 Activity 的 onCreate() 方法中隐藏系统栏，那么当用户按“主屏幕”按钮时，系统栏会重新出现。当用户重新打开 Activity 后，系统不会调用 onCreate()，因此系统栏仍保持可见。如果您希望在用户进入和退出 Activity 时继续保留系统界面更改，请在 onResume() 或 onWindowFocusChanged() 中设置界面标记。
//            方法 setSystemUiVisibility() 生效的前提是您调用它时所在的视图必须可见。
//            离开该视图会导致系统清除使用 setSystemUiVisibility() 设置的标记。
            int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;

            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                uiOptions |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
            }
            decorView.setSystemUiVisibility(uiOptions);
        }
    }

    /**
     * 隐藏导航栏
     */
    public void showNavigationBar(@NonNull Activity activity) {
        if (!isHasNavigationBar(activity)) {
            return;
        }

        showNavigationBar(activity.getWindow());
    }

    /**
     * 隐藏导航栏
     */
    private void showNavigationBar(@NonNull Window window) {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
            WindowInsetsController windowInsetsController = window.getInsetsController();
            windowInsetsController.show(WindowInsets.Type.navigationBars());
        } else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
            View decorView = window.getDecorView();
            decorView.setSystemUiVisibility(0);
        }
    }

    /**
     * @deprecated strongly recommend use style in theme impl
     */
    public void fullScreen(@NonNull Activity activity) {
        hideStatusBar(activity);
        hideNavigationBar(activity);
    }

    /**
     * @deprecated strongly recommend use style in theme impl
     */
    public void closeFullScreen(@NonNull Activity activity) {
        showStatusBar(activity);
        showNavigationBar(activity);
    }

    private boolean isFlymeOS4Later() {
        String version = new DeviceUtil().getFlymeVersionName();
        int num;
        if (!version.isEmpty()) {
            try {
                if (version.toLowerCase().contains("os")) {
                    num = Integer.parseInt(version.substring(9, 10));
                } else {
                    num = Integer.parseInt(version.substring(6, 7));
                }
                return num >= 4;
            } catch (NumberFormatException e) {
                return false;
            }
        }
        return false;
    }

    /**
     * orientation of current activity
     *
     * @param activity current activity
     */
    public boolean isPortrait(@NonNull Activity activity) {
        return (activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
    }

    /**
     * get navigation bar height of current activity
     *
     * @param activity current activity
     */
    public int getNavigationBarHeight(@NonNull Activity activity) {
        int result = 0;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            if (isHasNavigationBar(activity)) {
                String key;
                if (isPortrait(activity)) {
                    key = IMMERSION_NAVIGATION_BAR_HEIGHT;
                } else {
                    key = IMMERSION_NAVIGATION_BAR_HEIGHT_LANDSCAPE;
                }
                return getInternalDimensionSize(activity, key);
            }
        }
        return result;
    }

    private int getInternalDimensionSize(Context context, String key) {
        int result = 0;
        try {
            int resourceId = Resources.getSystem().getIdentifier(key, "dimen", "android");
            if (resourceId > 0) {
                int sizeOne = context.getResources().getDimensionPixelSize(resourceId);
                int sizeTwo = Resources.getSystem().getDimensionPixelSize(resourceId);

                if (sizeTwo >= sizeOne) {
                    return sizeTwo;
                } else {
                    float densityOne = context.getResources().getDisplayMetrics().density;
                    float densityTwo = Resources.getSystem().getDisplayMetrics().density;
                    float f = sizeOne * densityTwo / densityOne;
                    return (int) ((f >= 0) ? (f + 0.5f) : (f - 0.5f));
                }
            }
        } catch (Resources.NotFoundException ignored) {
            return 0;
        }
        return result;
    }

    public boolean isHasNavigationBar(Activity activity) {
        DeviceUtil deviceUtil = new DeviceUtil();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            //判断小米手机是否开启了全面屏，开启了，直接返回false
            if (Settings.Global.getInt(activity.getContentResolver(), IMMERSION_MIUI_NAVIGATION_BAR_HIDE_SHOW, 0) != 0) {
                return false;
            }
            //判断华为手机是否隐藏了导航栏，隐藏了，直接返回false
            if (deviceUtil.isEMUI()) {
                if (deviceUtil.isEMUI3_x() || Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
                    if (Settings.System.getInt(activity.getContentResolver(), IMMERSION_EMUI_NAVIGATION_BAR_HIDE_SHOW, 0) != 0) {
                        return false;
                    }
                } else {
                    if (Settings.Global.getInt(activity.getContentResolver(), IMMERSION_EMUI_NAVIGATION_BAR_HIDE_SHOW, 0) != 0) {
                        return false;
                    }
                }
            }
        }
        //其他手机根据屏幕真实高度与显示高度是否相同来判断
        WindowManager windowManager = activity.getWindowManager();
        Display d = windowManager.getDefaultDisplay();

        DisplayMetrics realDisplayMetrics = new DisplayMetrics();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            d.getRealMetrics(realDisplayMetrics);
        }

        int realHeight = realDisplayMetrics.heightPixels;
        int realWidth = realDisplayMetrics.widthPixels;

        DisplayMetrics displayMetrics = new DisplayMetrics();
        d.getMetrics(displayMetrics);

        int displayHeight = displayMetrics.heightPixels;
        int displayWidth = displayMetrics.widthPixels;

        return (realWidth - displayWidth) > 0 || (realHeight - displayHeight) > 0;
    }

    /**
     * 变色view
     * Transform view.
     */
    private void transformView(@NonNull View view, @ColorInt int colorBefore, @ColorInt int colorAfter,
                               @FloatRange(from = 0.0, to = 1.0) float ratio) {
        view.setBackgroundColor(ColorUtils.blendARGB(colorBefore, colorAfter, ratio));
    }

    /**
     * 获取系统亮度，需要WRITE_SETTINGS权限
     *
     * @param context 上下文
     * @return 亮度，范围是0-255；默认255
     */
    @RequiresPermission(Manifest.permission.WRITE_SETTINGS)
    public int getScreenBrightness(Context context) {
        return Settings.System.getInt(context.getContentResolver(),
                Settings.System.SCREEN_BRIGHTNESS, 255);
    }

    /**
     * 获取系统亮度，需要WRITE_SETTINGS权限
     *
     * @param activity 当前窗口
     * @return 0 to 1 adjusts the brightness from dark to full bright.
     */
    public float getWindowBrightness(Activity activity) {
        Window window = activity.getWindow();
        WindowManager.LayoutParams localLayoutParams = window.getAttributes();
        return localLayoutParams.screenBrightness;
    }

    /**
     * 设置系统亮度（此方法只是更改了系统的亮度属性，并不能看到效果。要想看到效果可以使用{@link #setWindowBrightness(Activity, float)}方法设置窗口的亮度），
     * 需要WRITE_SETTINGS权限
     *
     * @param context          上下文
     * @param screenBrightness 亮度，范围是0-255
     * @return 设置是否成功
     */
    @RequiresPermission(Manifest.permission.WRITE_SETTINGS)
    public boolean setScreenBrightness(Context context,
                                       int screenBrightness) {
        int brightness = screenBrightness;
        if (screenBrightness < 1) {
            brightness = 1;
        } else if (screenBrightness > 255) {
            brightness = screenBrightness % 255;
            if (brightness == 0) {
                brightness = 255;
            }
        }
        return Settings.System.putInt(context.getContentResolver(),
                Settings.System.SCREEN_BRIGHTNESS, brightness);
    }


    /**
     * 设置给定Activity的窗口的亮度（可以看到效果，但系统的亮度属性不会改变）
     *
     * @param activity         要通过此Activity来设置窗口的亮度
     * @param screenBrightness 亮度，范围是0-255
     */
    public void setWindowBrightness(Activity activity,
                                    float screenBrightness) {
        float brightness = screenBrightness;
        if (screenBrightness < 1) {
            brightness = 1;
        } else if (screenBrightness > 255) {
            brightness = screenBrightness % 255;
            if (brightness == 0) {
                brightness = 255;
            }
        }
        Window window = activity.getWindow();
        WindowManager.LayoutParams localLayoutParams = window.getAttributes();
        localLayoutParams.screenBrightness = (float) brightness / 255;
        window.setAttributes(localLayoutParams);
    }

    /**
     * 获取屏幕休眠时间，需要WRITE_SETTINGS权限
     *
     * @param context 上下文
     * @return 屏幕休眠时间，单位毫秒，默认30000
     */
    @RequiresPermission(Manifest.permission.WRITE_SETTINGS)
    public int getScreenDormantTime(Context context) {
        return Settings.System.getInt(context.getContentResolver(),
                Settings.System.SCREEN_OFF_TIMEOUT, 30000);
    }

    /**
     * 设置屏幕休眠时间，需要WRITE_SETTINGS权限
     *
     * @param context 上下文
     * @return 设置是否成功
     */
    @RequiresPermission(Manifest.permission.WRITE_SETTINGS)
    public boolean setScreenDormantTime(Context context, int millis) {
        return Settings.System.putInt(context.getContentResolver(),
                Settings.System.SCREEN_OFF_TIMEOUT, millis);
    }

}
